<template>
  <div class="app-container">
    <el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" inline>
      <el-form-item :label="$t('Department')" prop="deptId">
        <department-select v-model="queryParams.deptId" style="width: 200px" />
      </el-form-item>
      <el-form-item :label="$t('Name')" prop="name">
        <el-input v-model="queryParams.name" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <!-- <el-form-item :label="$t('device.State')" prop="state">
        <el-select v-model="queryParams.state" clearable>
          <el-option v-for="dict in dict.type.haij_device_state" :key="dict.value" :label="dict.label"
            :value="dict.value" />
        </el-select>
      </el-form-item> -->
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">
          {{ $t("Search") }}</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{
          $t("Reset")
        }}</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['device:device:create']">{{ $t("Add") }}</el-button>
      </el-col>
      <!-- <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
          v-hasPermi="['device:device:export']">{{ $t("Export") }}
        </el-button>
      </el-col> -->
      <right-toolbar :showSearch.sync="showSearch" @queryTable="queryPage"></right-toolbar>
    </el-row>

    <el-table ref="table" v-loading="loading" :data="list" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="45" align="center" />
      <el-table-column label="#" type="index" width="45" align="right">
        <template slot-scope="scope">
          <span>{{
            (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1
          }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('Name')" align="left" prop="name" min-width="150">
        <template slot-scope="{ row }">
          <el-button type="text" @click="handleControll(row)">{{
            row.name
          }}</el-button>
        </template>
      </el-table-column>
      <el-table-column :label="$t('Code')" align="left" prop="code" min-width="150" />
      <!-- <el-table-column :label="$t('Path')" align="left" prop="path" min-width="120" /> -->
      <!-- <el-table-column :label="$t('Category')" width="80">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.haij_device_type" :value="scope.row.type" />
        </template>
      </el-table-column> -->
      <el-table-column :label="$t('CreateTime')" align="left" prop="createTime" min-width="120" />
      <!-- <el-table-column :label="$t('Mode')" width="80">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.haij_device_mode" :value="scope.row.mode" />
        </template>
      </el-table-column> -->
      <!-- <el-table-column :label="$t('State')" align="center" prop="status" width="80">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.haij_device_status" :value="scope.row.status" />
        </template>
      </el-table-column> -->
      <el-table-column :label="$t('Online')" align="center" prop="state" width="66">
        <template slot-scope="{ row }">
          <i v-if="row.online" class="el-icon-success success">{{
            $t("Yes")
          }}</i>
          <i v-else class="el-icon-error info">{{ $t("No") }}</i>
        </template>
      </el-table-column>
      <el-table-column :label="$t('Operate')" align="center" width="120" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <!-- <el-button v-hasPermi="['device:child:page']" size="mini" type="text" @click="handleChild(scope.row)"
            :title="$t('Child')">{{ $t('Child') }}</el-button> -->
          <el-button v-hasPermi="['device:device:edit']" size="mini" type="text" icon="el-icon-edit"
            @click="handleUpdate(scope.row)" :title="$t('Modify')"></el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
            v-hasPermi="['device:device:remove']" :title="$t('Delete')"></el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
      @pagination="queryPage" />

    <el-dialog :title="title" :visible.sync="formVisible" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="120px">
        <el-form-item v-if="form.id" :label="$t('Category')" prop="type">
          <dict-tag :options="dict.type.haij_device_type" :value="form.type" />
        </el-form-item>
        <el-form-item :label="$t('Code')" prop="code">
          <el-input v-model="form.code" :placeholder="$t('device.InsertCode')" />
        </el-form-item>
        <el-form-item :label="$t('Department')" prop="deptId">
          <department-select v-model="form.deptId" :placeholder="$t('device.InsertDepartment')" />
        </el-form-item>
        <el-form-item :label="$t('Name')" prop="name">
          <el-input v-model="form.name" :placeholder="$t('device.InsertName')" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="formSubmit">{{ $t("OK") }}</el-button>
        <el-button @click="formCancel">{{ $t("Cancel") }}</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="form.name" :visible.sync="showController" width="420px">
      <div :is="controllerType" :value="form" />
    </el-dialog>
  </div>
</template>

<script>
  import DataEntity from "@/components/DataEntity/DataEntity";
  import deviceAPI from "@/api/device/device";
  import socketAPI from "@/api/socket/socket";
  import DepartmentSelect from "@/views/system/components/DepartmentSelect.vue";
  import PermissionDialogVue from '@/views/device/child/PermissionDialog.vue';
  import {
    DeviceController,
    ChargingController,
    LockerController
  } from "@/views/device/components/controller/index";
  import {
    controllerByType,
    stateTextByType
  } from '@/views/device/common'

  export default {
    name: "DevicePage",
    dicts: ["haij_device_type", "haij_device_mode", "haij_device_state"],
    mixins: [DataEntity],
    components: {
      DepartmentSelect,
      DeviceController,
      ChargingController,
      LockerController
    },
    data() {
      return {
        currentAPI: deviceAPI,
        currentBaseURL: '/device/device',
        currentCode: 'device',
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          subQuantity: null,
          code: null,
          name: null,
          type: 0,
          state: null,
          userId: null,
          deptId: null,
        },
        defaultForm: {
          id: null,
          name: null,
          code: null,
          type: null,
          deptId: null
        },
        rules: {
          name: [{
            max: 20,
            message: this.$t("MaxLengthIs", [20]),
          }],
          code: [{
            required: true,
            message: this.$t("device.CodeNull"),
            trigger: "blur",
          }, {
            max: 50,
            message: this.$t("MaxLengthIs", [50]),
          }],
          deptId: [{
            required: true,
            message: this.$t("common.DepartmentNull"),
            trigger: "blur",
          }]
        },
        controllerType: null,
        showController: false,
        permissionSelect: this.$SelectorConstructor(PermissionDialogVue)
      };
    },
    computed: {
      queryStateList() {
        const {
          type
        } = this.queryParams
        return stateTextByType(type)
      },
    },
    watch: {
      list(nv, ov) {
        if (!ov || ov.length == 0) {
          this.subscribeDevices(nv);
          return
        }
        if (!nv || nv.length === 0) {
          this.subscribeDevices(nv);
          return
        }
        const om = {}
        const nm = {}
        ov.forEach(item => {
          if (item.code) {
            om[item.code] = item
          }
        })
        nv.forEach(item => {
          if (item.code) {
            nm[item.code] = item
          }
        })
        Object.keys(nm).forEach(k => {
          if (nm[k]) {
            delete om[k]
            delete nm[k]
          }
        })
        const removeList = []
        const addList = []
        Object.values(om).forEach(v => {
          removeList.push(v)
        })
        Object.values(nm).forEach(v => {
          addList.push(v)
        })
        this.unsubscribeDevices(removeList);
        this.subscribeDevices(addList);
      },
    },
    created() {
      this.subscribeDevices(this.list)
      socketAPI.addHandle(this.websocketReceive);
    },
    methods: {
      // 节点单击事件
      handleDepartmentSelected(data) {
        this.queryParams.deptId = data.id;
        this.handleQuery();
      },
      // 表单重置
      reset() {
        this.form = {
          id: null,
          code: null,
          name: null,
          category: null,
          type: null,
          state: null,
          path: null,
          mojorNumber: null,
          deptId: null,
        };
        this.resetForm("form");
      },
      /** 重置按钮操作 */
      resetQuery() {
        this.resetForm("queryForm");
        this.queryParams.deptId = undefined;
        this.handleQuery();
      },
      // 多选框选中数据
      handleSelectionChange(selection) {
        this.selections = [].concat(selection)
        this.ids = selection.map((item) => item.id);
        this.singleDisable = selection.length !== 1;
        this.multipleDisable = selection.length === 0;
      },
      handleUser(row) {
        this.userSelect({
          // query:{},
          refresh: true,
          multiple: true,
          params: {
            device: Object.assign({}, row)
          },
          callback(value) {

          }
        })
      },
      subscribeDevices(list) {
        if (!list || list.length === 0) {
          return;
        }
        // list.forEach((item) => {
        //   if (!item.code) {
        //     return;
        //   }
        //   socketAPI.subscribe(item.code);
        // });
        socketAPI.subscribe(list.map((item) => item.code));
      },
      unsubscribeDevices(list) {
        if (!list || list.length === 0) {
          return;
        }
        // list.forEach((item) => {
        //   if (!item.code) {
        //     return;
        //   }
        //   socketAPI.unsubscribe(item.code);
        // });
        socketAPI.unsubscribe(list.map((item) => item.code));
      },
      handleControll(row) {
        try {
          this.controllerType = controllerByType(row.type)
          this.form = Object.assign({}, row)
          this.showController = true;
        } catch (e) {
          this.$message({
            type: 'warning',
            message: this.$t(e.message)
          })
        }
      },
      websocketReceive(json) {
        if (!this.list || this.list.length == 0) {
          return
        }
        this.list.forEach((item) => {
          if (json.code !== item.code) {
            return;
          }
          const {
            online
          } = json;
          item.online = online;
          switch (json.type) {
            case 0: {
              const {
                state,
                leaveMinute,
                timingMinute,
                current
              } = json;
              item.state = state;
              item.leaveMinute = leaveMinute;
              item.timingMinute = timingMinute;
              item.current = current;
              break;
            }
          }
        });
      },
      handleBindDevice(row) {
        this.permissionSelect({
          refresh: true,
          multiple: true,
          params: {
            deviceChild: {
              deviceId: row.id,
              index: -1
            }
          }
        })
      },
      selectionCommand(command) {
        this.selections.forEach(item => {
          const {
            online,
            code
          } = item
          if (!online) {
            return
          }
          deviceAPI.command({
            code,
            command
          })
        })
        this.$refs['table'].clearSelection()
      }
    },
  };

</script>
